"""
    正则表达式是一个强大的字符串处理工具，几乎所有的字符串操作都可以通过正则表达式来完成，其本质是一个特殊的字符序列，可以
    方便的检查一个字符串是否可以与我们定义的字符串序列的某种模式相匹配

    正则表达式并不是Python所特有，几乎所有编程语言都支持正则表达式，Python提供了内置模块re和第三方模块regex来支持正则表达式，
    regex模块提供了与re模块兼容的api接口，同时还提供了额外的功能和更加全面的Unicode支持，本文只介绍re模块。


    .                                           默认情况，匹配除了换行的任意字符；如果指定了标签DOTALL，则匹配包含换行符的任意字符
    ^                                           匹配字符串的开头，在MULTILINE模式也匹配换行后的首个符号
    $                                           匹配字符串尾或者换行符的前一个字符，在 MULTILINE 模式匹配换行符的前一个字符

    *                                           匹配一个字符0到无限次
    +                                           匹配一个字符1到无限次
    ?                                           匹配一个字符0次或1次
    {m}                                         匹配一个字符m次
    {m,n}                                       匹配一个字符m到n次
    *? +? ?? {m,n}?                             使 *、+、？、{m,n} 变成非贪婪模式，也就是使这些匹配次数不定的表达式尽可能少的匹配

    \                                           转义特殊字符
    [...]                                       用于表示一个字符集合
    |                                           匹配 | 两边任意表达式
    (...)                                       将括起来的表达式分组，
    (?aiLmsux)                                  aiLmsux 每一个字符代表一个匹配模式，可选多个
    (?:…)                                       (…) 的不分组版本
    (?P<name>…)                                 分组，除了原有的编号外再指定一个额外的别名
    (?P=name)	                                引用别名为 name 的分组匹配到的字符串
    (?#…)	                                    # 后面的将作为注释被忽略
    (?=…)	                                    匹配 … 的内容，但是并不消费样式的内容
    (?!…)	                                    匹配 … 不符合的情况
    (?<=…)	                                    匹配字符串的当前位置，它的前面匹配 … 的内容到当前位置
    (?<!…)	                                    匹配当前位置之前不是 … 的样式
    (?(id/name)yes-pattern|no-pattern)	        如果给定的 id 或 name 存在，将会尝试匹配 yes-pattern ，否则就尝试匹配 no-pattern，no-pattern 可选，也可以被忽略
    \number	                                    匹配数字代表的组合
    \A	                                        只匹配字符串开始
    \b	                                        匹配空字符串，但只在单词开始或结尾的位置
    \B	                                        匹配空字符串，但不能在词的开头或者结尾
    \d	                                        主要匹配数字 [0-9]
    \D	                                        匹配任何非十进制数字的字符
    \s	                                        匹配空白字符，主要包括：空格 \t \n \r \f \v
    \S	                                        匹配任何非空白字符
    \w	                                        匹配 [a-zA-Z0-9_]
    \W	                                        匹配非单词字符
    \Z	                                        只匹配字符串尾

"""
import re

# . (匹配任意字符)
print("\n======================. (匹配任意字符)=====================\n")
text = "Hello World"
pattern = r'H.llo'  # . 匹配任意一个字符

match = re.search(pattern, text)
print(match.group())  # 输出: Hello

print("\n=======================^ (匹配字符串开头)====================\n")
text = "Hello World"
pattern = r'^Hello'  # 匹配字符串开头

match = re.search(pattern, text)
print(match.group())  # 输出: Hello

print("\n=======================$ (匹配字符串结尾)===================\n")
text = "Hello World"
pattern = r'World$'  # 匹配字符串结尾

match = re.search(pattern, text)
print(match.group())  # 输出: World

print("\n=======================* (匹配前一个字符 0 到无限次)===================\n")
text = "aaaabbb"
pattern = r'a*'  # 匹配 0 到多个 'a'

match = re.search(pattern, text)
print(match.group())  # 输出: aaaa

print("\n=======================+ (匹配前一个字符 1 到无限次)===================\n")
text = "aaaabbb"
pattern = r'a+'  # 匹配 1 到多个 'a'

match = re.search(pattern, text)
print(match.group())  # 输出: aaaa

print("\n=======================? (匹配前一个字符 0 次或 1 次)===================\n")
text = "color bax"
pattern = r'colou?r'  # 'u' 是可选的

match = re.search(pattern, text)
print(match.group())  # 输出: color

print("\n======================={m} (匹配前一个字符 m 次)===================\n")

text = "aaaabbb"
pattern = r'a{3}'  # 匹配 3 个 'a'

match = re.search(pattern, text)
print(match.group())  # 输出: aaa

print("\n======================={m,n} (匹配前一个字符 m 到 n 次) ===================\n")
text = "aaaabbb"
pattern = r'a{2,4}'  # 匹配 2 到 4 个 'a'

match = re.search(pattern, text)
print(match.group())  # 输出: aaaa

print("\n======================= 非贪婪模式 *?, +?, ??, {m,n}? ===================\n")
text = "<div>Content 1</div><div>Content 2</div>"
pattern = r'<div>(.*?)</div>'  # 非贪婪匹配
# pattern = r'<div>(.*)</div>'   # 贪婪模式
matches = re.findall(pattern, text)
print(matches)  # 输出: ['Content 1', 'Content 2']

print("\n======================= \ (转义特殊字符) ===================\n")
text = "3 + 5 = 8"
pattern = r'\+'  # 匹配加号

match = re.search(pattern, text)
print(match.group())  # 输出: +

print("\n======================= [...] (字符集合) ===================\n")
text = "abc123"
pattern = r'[a-z]'  # 匹配小写字母

matches = re.findall(pattern, text)
print(matches)  # 输出: ['a', 'b', 'c']
print(''.join(matches))

print("\n======================= | (匹配任意表达式) ===================\n")
text = "apple orange banana"
pattern = r'apple|banana'  # 匹配 apple 或 banana

matches = re.findall(pattern, text)
print(matches)  # 输出: ['apple', 'banana']

print("\n======================= (...) (分组) ===================\n")
text = "Hello World"
pattern = r'(Hello) (World)'  # 分组匹配

match = re.search(pattern, text)
if match:
    print("分组1:", match.group(1))  # 输出: Hello
    print("分组2:", match.group(2))  # 输出: World

print("\n======================= (?aiLmsux) (指定匹配模式) ===================\n")

text = "hello"
pattern = r'(?i)HELLO'  # 忽略大小写匹配
'''
    a: 仅在 ASCII 字符集上进行匹配（re.ASCII）。
    i: 忽略大小写匹配（re.IGNORECASE），即 A 和 a 被视为相同。
    L: 使用当前语言环境进行匹配（re.LOCALE）。这个标志在国际化时很有用。
    m: 多行模式（re.MULTILINE），使 ^ 和 $ 匹配每一行的开头和结尾，而不仅仅是整个字符串的开头和结尾。
    s: 单行模式（re.DOTALL），使 . 匹配包括换行符在内的所有字符。
    u: 使用 Unicode 字符集（re.UNICODE），使得 \w, \b, \s 等能够匹配 Unicode 字符。
    x: 允许在正则表达式中使用空格和注释（re.VERBOSE），使得正则表达式更易于阅读。
'''
match = re.search(pattern, text)
print(match.group())  # 输出: hello

text = "Hello World\nhello world"
# 使用多个标志
pattern = r'(?im)(hello)'  # 忽略大小写和多行模式
matches = re.findall(pattern, text)
print(matches)  # 输出: ['Hello', 'hello']

print("\n======================= (?:...) (非捕获分组) ===================\n")
text = "Hello World"
pattern = r'Hello (?:World|Everyone)'  # 非捕获分组

match = re.search(pattern, text)
print(match.group())  # 输出: Hello World

print('\n========================(?=...) (正向前瞻)=====================\n')
import re

text = "Python is fun"
pattern = r'Python(?= is)'  # 匹配 'Python' 后面跟着 ' is'

match = re.search(pattern, text)
print(match.group())  # 输出: Python

print('\n========================(?=...) (负向前瞻) =====================\n')
# 负向前瞻用于匹配某个模式，但不允许后面跟随另一个模式。

text = "Python is fun"
pattern = r'Python(?! is)'  # 匹配 'Python' 后面不跟 ' is'

match = re.search(pattern, text)
print(match)  #None

print('\n======================== (?!...) (负向前瞻) =====================\n')
# 负向前瞻用于匹配某个模式，但不允许后面跟随另一个模式。
import re

text = "Python is fun"
pattern = r'Python(?! is)'  # 匹配 'Python' 后面不跟 ' is'

match = re.search(pattern, text)
print(match)  #